// Copyright 2013 bee authors
//
// Licensed under the Apache License, Version 2.0 (the "License"): you may
// not use this file except in compliance with the License. You may obtain
// a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
// License for the specific language governing permissions and limitations
// under the License.

package main

import (
	"fmt"
	"os"
	path "path/filepath"
	"strings"
)

var cmdNew = &Command{
	UsageLine: "new [appname]",
	Short:     "create a xl_go application",
	Long: `
Creates a xl_go application for the given app name in the current directory.

The command 'new' creates a folder named [appname] and inside the folder deploy
the following files/directories structure:

─Project 项目开发目录
├─logger 运行日志输出目录
└─main.go 应用入口文件
`,
}

func init() {
	cmdNew.Run = createApp
}

var importPrefix string

func createApp(cmd *Command, args []string) int {
	curpath, _ := os.Getwd()
	if len(args) != 1 {
		ColorLog("[ERRO] Argument [appname] is missing\n")
		os.Exit(2)
	}

	gopath := os.Getenv("GOPATH")
	Debugf("gopath:%s", gopath)
	if gopath == "" {
		ColorLog("[ERRO] $GOPATH not found\n")
		ColorLog("[HINT] Set $GOPATH in your environment vairables\n")
		os.Exit(2)
	}
	haspath := false
	appsrcpath := ""

	wgopath := path.SplitList(gopath)
	for _, wg := range wgopath {

		wg = path.Join(wg, "src")

		if strings.HasPrefix(strings.ToLower(curpath), strings.ToLower(wg)) {
			haspath = true
			appsrcpath = wg
			break
		}

		wg, _ = path.EvalSymlinks(wg)

		if strings.HasPrefix(strings.ToLower(curpath), strings.ToLower(wg)) {
			haspath = true
			appsrcpath = wg
			break
		}

	}

	if !haspath {
		ColorLog("[ERRO] Unable to create an application outside of $GOPATH%ssrc(%s%ssrc)\n", string(path.Separator), gopath, string(path.Separator))
		ColorLog("[HINT] Change your work directory by `cd ($GOPATH%ssrc)`\n", string(path.Separator))
		os.Exit(2)
	}

	appname := args[0]
	apppath := path.Join(curpath, appname)
	importPrefix = strings.Join(strings.Split(apppath[len(appsrcpath)+1:], string(path.Separator)), "/")

	if isExist(apppath) {
		ColorLog("[ERRO] Path (%s) already exists\n", apppath)
		ColorLog("[WARN] Do you want to overwrite it? [yes|no]]")
		if !askForConfirmation() {
			os.Exit(2)
		}
	}

	fmt.Println("[INFO] Creating application...")

	mrkdir(apppath)

	writetofile(
		createContent(maingo),
		apppath, "main.go",
	)

	ColorLog("[SUCC] New application successfully created!\n")
	return 0
}

func mrkdir(p ...string) {
	pt := path.Join(p...)
	os.Mkdir(pt, 0777)
	fmt.Println(pt + string(path.Separator))
}

func writetofile(content string, filepath ...string) {
	filename := path.Join(filepath...)
	fmt.Println(filename)
	f, err := os.OpenFile(filename, os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0777)
	if err != nil {
		panic(err)
	}
	defer f.Close()
	f.WriteString(content)
}

func createContent(tpl string) string {
	return strings.Replace(tpl, "[[[importPrefix]]]", importPrefix, -1)
}

var maingo = `package main

import (
    "fmt"
)

func main() {
    fmt.Println("Creating application")
}
`
